package com.duobaoyu.dby.supply.biz.strategy.message.refund;

import com.alibaba.fastjson.JSON;
import com.duobaoyu.dby.channel.adapter.bean.message.refund.AfterSaleStatusMessage;
import com.duobaoyu.dby.channel.adapter.bean.refund.AfterSaleOrderInfo;
import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.channel.adapter.enums.biz.refund.AfterSaleStatusEnum;
import com.duobaoyu.dby.channel.boundary.bean.refund.result.AfterSaleParticularResult;
import com.duobaoyu.dby.common.mybatis.util.EnumUtils;
import com.duobaoyu.dby.supply.biz.constant.OperateSourceConstants;
import com.duobaoyu.dby.supply.biz.enums.AfterSaleSourceEnum;
import com.duobaoyu.dby.supply.common.biz.bo.refund.AfterSaleOutBO;
import com.duobaoyu.dby.supply.common.biz.bo.refund.AfterSaleStateContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yw
 * @description
 * @date 2023/10/13 17:22
 */
@Slf4j
@Component
public class LinkedMallAfterSaleStatusAsyncHandler extends AbstractChannelAfterSaleStateChangeHandler {
    @Override
    protected Set<String> channelCodes() {
        return Sets.newHashSet(ChannelCodeEnum.LINKED_MALL.getValue());
    }

    @Override
    protected Void handler(AfterSaleStateChangeMessageAsyncHandler.Context context,
                           Object beforeResult) {
        List<AfterSaleStatusMessage> channelAfterSaleMessages = context.getOriginMessages();
        List<AfterSaleOutBO> afterSaleItems = context.getAfterSales();
        Map<String, AfterSaleOutBO> afterSales = afterSaleItems.stream()
                .collect(Collectors.toMap(AfterSaleOutBO::getChannelAfterSaleSn, Function.identity(), (k1, k2) -> k1));

        List<AfterSaleStateContext> afterSaleStateContextList = Lists.newArrayList();
        List<AfterSaleStatusMessage> failureMessages = Lists.newArrayList();
        for (AfterSaleStatusMessage afterSaleMessage : channelAfterSaleMessages) {
            String channelAfterSaleSn = afterSaleMessage.getChannelAfterSaleSn();
            if (StringUtils.isBlank(channelAfterSaleSn)) {
                log.error("售后申请结果回调，无渠道售后编号,param={}", JSON.toJSONString(afterSaleMessage));
                continue;
            }
            try {
                AfterSaleOutBO afterSale = afterSales.get(channelAfterSaleSn);
                AfterSaleParticularResult afterSaleParticularResult = afterSaleBoundaryClient.queryAfterSale(afterSale);
                AfterSaleOrderInfo afterSaleOrderInfo = afterSaleParticularResult.getAfterSaleOrderInfo();
                Integer afterSaleStatus = afterSaleOrderInfo.getAfterSaleStatus();
                if (EnumUtils.eq(AfterSaleStatusEnum.TO_BE_CONFIRMED_BY_USER,afterSaleOrderInfo.getAfterSaleStatus())
                        && EnumUtils.eq(AfterSaleSourceEnum.SYSTEM,afterSale.getAfterSaleSource())) {
                    afterSaleStatus = AfterSaleStatusEnum.COMPLETED.getValue();
                }
                List<AfterSaleStateContext.AfterSaleUpdateItemInfo> afterSaleUpdateItemInfos = buildRefundInfo(afterSaleOrderInfo.getChannelRealRefundAmount(),
                        afterSaleOrderInfo.getChannelFreightRefundAmount(), afterSale);
                // 退款
                BigDecimal channelActualRefundAmount = null,
                        channelFreightActualRefundAmount = null;

                if (Objects.nonNull(afterSaleOrderInfo.getChannelRealRefundAmount())) {
                    channelActualRefundAmount = afterSaleUpdateItemInfos.stream().map(AfterSaleStateContext.AfterSaleUpdateItemInfo::getChannelActualRefundAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    channelFreightActualRefundAmount = afterSaleUpdateItemInfos.stream().map(AfterSaleStateContext.AfterSaleUpdateItemInfo::getChannelFreightActualRefundAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                }
                AfterSaleStateContext afterSaleContext = new AfterSaleStateContext();
                afterSaleContext.setAfterSale(afterSale);
                afterSaleContext.setCurrentAfterSaleStatus(afterSaleStatus);
                afterSaleContext.setOperateSource(OperateSourceConstants.OPERATION_CHANNEL);
                afterSaleContext.setChangeContentOperate(AfterSaleStateContext.ChangeContentOperate.builder()
                        .channelAfterSaleSn(afterSaleParticularResult.getChannelAfterSaleSn())
                        .failReason(afterSaleOrderInfo.getRejectReason())
                        .afterSaleItemInfoList(afterSaleUpdateItemInfos)
                        .channelActualRefundAmount(channelActualRefundAmount)
                        .channelFreightActualRefundAmount(channelFreightActualRefundAmount)
                        .build());
                afterSaleStateContextList.add(afterSaleContext);
            } catch (Exception e) {
                failureMessages.add(afterSaleMessage);
            }
        }
        context.setHandleSuccessMessages(afterSaleStateContextList);
        context.setHandleFailureMessages(failureMessages);
        return null;
    }

//    private AfterSaleStateContext.RefundInfo buildRefundInfo(AfterSaleParticularResult result, AfterSaleOutBO afterSale) {
//        AfterSaleOrderInfo afterSaleInfo = result.getAfterSaleOrderInfo();
//
//        if (AfterSaleStatusEnum.TO_BE_CONFIRMED_BY_USER.getValue().equals(afterSaleInfo.getAfterSaleStatus())) {
//            List<AfterSaleItemOutBO> items = afterSale.getItems();
//            AfterSaleItemOutBO first = CollUtil.getFirst(items);
//            AfterSaleStateContext.RefundItem refundItem = new AfterSaleStateContext.RefundItem();
//            refundItem.setSkuCode(first.getSkuCode());
//            refundItem.setChannelActualRefundAmount(afterSaleInfo.getChannelRealRefundAmount());
//            refundItem.setChannelFreightActualRefundAmount(afterSaleInfo.getChannelFreightRefundAmount());
//
//            AfterSaleStateContext.RefundInfo refundInfo = new AfterSaleStateContext.RefundInfo();
//            refundInfo.setRefundAmount(afterSaleInfo.getChannelRealRefundAmount());
//            refundInfo.setFreightRefundAmount(afterSaleInfo.getChannelFreightRefundAmount());
//            refundInfo.setItems(Lists.newArrayList(refundItem));
//            return refundInfo;
//        }
//        return null;
//    }
}
